// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Requests;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;
using Elastic.Transport.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.TransformManagement;

public sealed partial class PutTransformRequestParameters : RequestParameters
{
	/// <summary>
	/// <para>
	/// When the transform is created, a series of validations occur to ensure its success. For example, there is a
	/// check for the existence of the source indices and a check that the destination index is not part of the source
	/// index pattern. You can use this parameter to skip the checks, for example when the source index does not exist
	/// until after the transform is created. The validations are always run when you start the transform, however, with
	/// the exception of privilege checks.
	/// </para>
	/// </summary>
	public bool? DeferValidation { get => Q<bool?>("defer_validation"); set => Q("defer_validation", value); }

	/// <summary>
	/// <para>
	/// Period to wait for a response. If no response is received before the timeout expires, the request fails and returns an error.
	/// </para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Duration? Timeout { get => Q<Elastic.Clients.Elasticsearch.Duration?>("timeout"); set => Q("timeout", value); }
}

/// <summary>
/// <para>
/// Create a transform.
/// Creates a transform.
/// </para>
/// <para>
/// A transform copies data from source indices, transforms it, and persists it into an entity-centric destination index. You can also think of the destination index as a two-dimensional tabular data structure (known as
/// a data frame). The ID for each document in the data frame is generated from a hash of the entity, so there is a
/// unique row per entity.
/// </para>
/// <para>
/// You must choose either the latest or pivot method for your transform; you cannot use both in a single transform. If
/// you choose to use the pivot method for your transform, the entities are defined by the set of <c>group_by</c> fields in
/// the pivot object. If you choose to use the latest method, the entities are defined by the <c>unique_key</c> field values
/// in the latest object.
/// </para>
/// <para>
/// You must have <c>create_index</c>, <c>index</c>, and <c>read</c> privileges on the destination index and <c>read</c> and
/// <c>view_index_metadata</c> privileges on the source indices. When Elasticsearch security features are enabled, the
/// transform remembers which roles the user that created it had at the time of creation and uses those same roles. If
/// those roles do not have the required privileges on the source and destination indices, the transform fails when it
/// attempts unauthorized operations.
/// </para>
/// <para>
/// NOTE: You must use Kibana or this API to create a transform. Do not add a transform directly into any
/// <c>.transform-internal*</c> indices using the Elasticsearch index API. If Elasticsearch security features are enabled, do
/// not give users any privileges on <c>.transform-internal*</c> indices. If you used transforms prior to 7.5, also do not
/// give users any privileges on <c>.data-frame-internal*</c> indices.
/// </para>
/// </summary>
public sealed partial class PutTransformRequest : PlainRequest<PutTransformRequestParameters>
{
	public PutTransformRequest(Elastic.Clients.Elasticsearch.Id transformId) : base(r => r.Required("transform_id", transformId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.TransformManagementPutTransform;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "transform.put_transform";

	/// <summary>
	/// <para>
	/// When the transform is created, a series of validations occur to ensure its success. For example, there is a
	/// check for the existence of the source indices and a check that the destination index is not part of the source
	/// index pattern. You can use this parameter to skip the checks, for example when the source index does not exist
	/// until after the transform is created. The validations are always run when you start the transform, however, with
	/// the exception of privilege checks.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? DeferValidation { get => Q<bool?>("defer_validation"); set => Q("defer_validation", value); }

	/// <summary>
	/// <para>
	/// Period to wait for a response. If no response is received before the timeout expires, the request fails and returns an error.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public Elastic.Clients.Elasticsearch.Duration? Timeout { get => Q<Elastic.Clients.Elasticsearch.Duration?>("timeout"); set => Q("timeout", value); }

	/// <summary>
	/// <para>
	/// Free text description of the transform.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("description")]
	public string? Description { get; set; }

	/// <summary>
	/// <para>
	/// The destination for the transform.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("dest")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Destination Dest { get; set; }

	/// <summary>
	/// <para>
	/// The interval between checks for changes in the source indices when the transform is running continuously. Also
	/// determines the retry interval in the event of transient failures while the transform is searching or indexing.
	/// The minimum value is <c>1s</c> and the maximum is <c>1h</c>.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("frequency")]
	public Elastic.Clients.Elasticsearch.Duration? Frequency { get; set; }

	/// <summary>
	/// <para>
	/// The latest method transforms the data by finding the latest document for each unique key.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("latest")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Latest? Latest { get; set; }

	/// <summary>
	/// <para>
	/// Defines optional transform metadata.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("_meta")]
	public IDictionary<string, object>? Meta { get; set; }

	/// <summary>
	/// <para>
	/// The pivot method transforms the data by aggregating and grouping it. These objects define the group by fields
	/// and the aggregation to reduce the data.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("pivot")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Pivot? Pivot { get; set; }

	/// <summary>
	/// <para>
	/// Defines a retention policy for the transform. Data that meets the defined criteria is deleted from the
	/// destination index.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("retention_policy")]
	public Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicy? RetentionPolicy { get; set; }

	/// <summary>
	/// <para>
	/// Defines optional transform settings.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("settings")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Settings? Settings { get; set; }

	/// <summary>
	/// <para>
	/// The source of the data for the transform.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("source")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Source Source { get; set; }

	/// <summary>
	/// <para>
	/// Defines the properties transforms require to run continuously.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("sync")]
	public Elastic.Clients.Elasticsearch.TransformManagement.Sync? Sync { get; set; }
}

/// <summary>
/// <para>
/// Create a transform.
/// Creates a transform.
/// </para>
/// <para>
/// A transform copies data from source indices, transforms it, and persists it into an entity-centric destination index. You can also think of the destination index as a two-dimensional tabular data structure (known as
/// a data frame). The ID for each document in the data frame is generated from a hash of the entity, so there is a
/// unique row per entity.
/// </para>
/// <para>
/// You must choose either the latest or pivot method for your transform; you cannot use both in a single transform. If
/// you choose to use the pivot method for your transform, the entities are defined by the set of <c>group_by</c> fields in
/// the pivot object. If you choose to use the latest method, the entities are defined by the <c>unique_key</c> field values
/// in the latest object.
/// </para>
/// <para>
/// You must have <c>create_index</c>, <c>index</c>, and <c>read</c> privileges on the destination index and <c>read</c> and
/// <c>view_index_metadata</c> privileges on the source indices. When Elasticsearch security features are enabled, the
/// transform remembers which roles the user that created it had at the time of creation and uses those same roles. If
/// those roles do not have the required privileges on the source and destination indices, the transform fails when it
/// attempts unauthorized operations.
/// </para>
/// <para>
/// NOTE: You must use Kibana or this API to create a transform. Do not add a transform directly into any
/// <c>.transform-internal*</c> indices using the Elasticsearch index API. If Elasticsearch security features are enabled, do
/// not give users any privileges on <c>.transform-internal*</c> indices. If you used transforms prior to 7.5, also do not
/// give users any privileges on <c>.data-frame-internal*</c> indices.
/// </para>
/// </summary>
public sealed partial class PutTransformRequestDescriptor<TDocument> : RequestDescriptor<PutTransformRequestDescriptor<TDocument>, PutTransformRequestParameters>
{
	internal PutTransformRequestDescriptor(Action<PutTransformRequestDescriptor<TDocument>> configure) => configure.Invoke(this);

	public PutTransformRequestDescriptor(Elastic.Clients.Elasticsearch.Id transformId) : base(r => r.Required("transform_id", transformId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.TransformManagementPutTransform;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "transform.put_transform";

	public PutTransformRequestDescriptor<TDocument> DeferValidation(bool? deferValidation = true) => Qs("defer_validation", deferValidation);
	public PutTransformRequestDescriptor<TDocument> Timeout(Elastic.Clients.Elasticsearch.Duration? timeout) => Qs("timeout", timeout);

	public PutTransformRequestDescriptor<TDocument> TransformId(Elastic.Clients.Elasticsearch.Id transformId)
	{
		RouteValues.Required("transform_id", transformId);
		return Self;
	}

	private string? DescriptionValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Destination DestValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor DestDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor> DestDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Latest? LatestValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor<TDocument> LatestDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor<TDocument>> LatestDescriptorAction { get; set; }
	private IDictionary<string, object>? MetaValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Pivot? PivotValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor<TDocument> PivotDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor<TDocument>> PivotDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicy? RetentionPolicyValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor<TDocument> RetentionPolicyDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor<TDocument>> RetentionPolicyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Settings? SettingsValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor SettingsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor> SettingsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Source SourceValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor<TDocument> SourceDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor<TDocument>> SourceDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Sync? SyncValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor<TDocument> SyncDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor<TDocument>> SyncDescriptorAction { get; set; }

	/// <summary>
	/// <para>
	/// Free text description of the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Description(string? description)
	{
		DescriptionValue = description;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The destination for the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Dest(Elastic.Clients.Elasticsearch.TransformManagement.Destination dest)
	{
		DestDescriptor = null;
		DestDescriptorAction = null;
		DestValue = dest;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Dest(Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor descriptor)
	{
		DestValue = null;
		DestDescriptorAction = null;
		DestDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Dest(Action<Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor> configure)
	{
		DestValue = null;
		DestDescriptor = null;
		DestDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval between checks for changes in the source indices when the transform is running continuously. Also
	/// determines the retry interval in the event of transient failures while the transform is searching or indexing.
	/// The minimum value is <c>1s</c> and the maximum is <c>1h</c>.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The latest method transforms the data by finding the latest document for each unique key.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Latest(Elastic.Clients.Elasticsearch.TransformManagement.Latest? latest)
	{
		LatestDescriptor = null;
		LatestDescriptorAction = null;
		LatestValue = latest;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Latest(Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor<TDocument> descriptor)
	{
		LatestValue = null;
		LatestDescriptorAction = null;
		LatestDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Latest(Action<Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor<TDocument>> configure)
	{
		LatestValue = null;
		LatestDescriptor = null;
		LatestDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines optional transform metadata.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
	{
		MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The pivot method transforms the data by aggregating and grouping it. These objects define the group by fields
	/// and the aggregation to reduce the data.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Pivot(Elastic.Clients.Elasticsearch.TransformManagement.Pivot? pivot)
	{
		PivotDescriptor = null;
		PivotDescriptorAction = null;
		PivotValue = pivot;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Pivot(Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor<TDocument> descriptor)
	{
		PivotValue = null;
		PivotDescriptorAction = null;
		PivotDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Pivot(Action<Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor<TDocument>> configure)
	{
		PivotValue = null;
		PivotDescriptor = null;
		PivotDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines a retention policy for the transform. Data that meets the defined criteria is deleted from the
	/// destination index.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> RetentionPolicy(Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicy? retentionPolicy)
	{
		RetentionPolicyDescriptor = null;
		RetentionPolicyDescriptorAction = null;
		RetentionPolicyValue = retentionPolicy;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> RetentionPolicy(Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor<TDocument> descriptor)
	{
		RetentionPolicyValue = null;
		RetentionPolicyDescriptorAction = null;
		RetentionPolicyDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> RetentionPolicy(Action<Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor<TDocument>> configure)
	{
		RetentionPolicyValue = null;
		RetentionPolicyDescriptor = null;
		RetentionPolicyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines optional transform settings.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Settings(Elastic.Clients.Elasticsearch.TransformManagement.Settings? settings)
	{
		SettingsDescriptor = null;
		SettingsDescriptorAction = null;
		SettingsValue = settings;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Settings(Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor descriptor)
	{
		SettingsValue = null;
		SettingsDescriptorAction = null;
		SettingsDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Settings(Action<Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor> configure)
	{
		SettingsValue = null;
		SettingsDescriptor = null;
		SettingsDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The source of the data for the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Source(Elastic.Clients.Elasticsearch.TransformManagement.Source source)
	{
		SourceDescriptor = null;
		SourceDescriptorAction = null;
		SourceValue = source;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Source(Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor<TDocument> descriptor)
	{
		SourceValue = null;
		SourceDescriptorAction = null;
		SourceDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Source(Action<Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor<TDocument>> configure)
	{
		SourceValue = null;
		SourceDescriptor = null;
		SourceDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines the properties transforms require to run continuously.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor<TDocument> Sync(Elastic.Clients.Elasticsearch.TransformManagement.Sync? sync)
	{
		SyncDescriptor = null;
		SyncDescriptorAction = null;
		SyncValue = sync;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Sync(Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor<TDocument> descriptor)
	{
		SyncValue = null;
		SyncDescriptorAction = null;
		SyncDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor<TDocument> Sync(Action<Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor<TDocument>> configure)
	{
		SyncValue = null;
		SyncDescriptor = null;
		SyncDescriptorAction = configure;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(DescriptionValue))
		{
			writer.WritePropertyName("description");
			writer.WriteStringValue(DescriptionValue);
		}

		if (DestDescriptor is not null)
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, DestDescriptor, options);
		}
		else if (DestDescriptorAction is not null)
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor(DestDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, DestValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (LatestDescriptor is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, LatestDescriptor, options);
		}
		else if (LatestDescriptorAction is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor<TDocument>(LatestDescriptorAction), options);
		}
		else if (LatestValue is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, LatestValue, options);
		}

		if (MetaValue is not null)
		{
			writer.WritePropertyName("_meta");
			JsonSerializer.Serialize(writer, MetaValue, options);
		}

		if (PivotDescriptor is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, PivotDescriptor, options);
		}
		else if (PivotDescriptorAction is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor<TDocument>(PivotDescriptorAction), options);
		}
		else if (PivotValue is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, PivotValue, options);
		}

		if (RetentionPolicyDescriptor is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, RetentionPolicyDescriptor, options);
		}
		else if (RetentionPolicyDescriptorAction is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor<TDocument>(RetentionPolicyDescriptorAction), options);
		}
		else if (RetentionPolicyValue is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, RetentionPolicyValue, options);
		}

		if (SettingsDescriptor is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, SettingsDescriptor, options);
		}
		else if (SettingsDescriptorAction is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor(SettingsDescriptorAction), options);
		}
		else if (SettingsValue is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, SettingsValue, options);
		}

		if (SourceDescriptor is not null)
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, SourceDescriptor, options);
		}
		else if (SourceDescriptorAction is not null)
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor<TDocument>(SourceDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, SourceValue, options);
		}

		if (SyncDescriptor is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, SyncDescriptor, options);
		}
		else if (SyncDescriptorAction is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor<TDocument>(SyncDescriptorAction), options);
		}
		else if (SyncValue is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, SyncValue, options);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Create a transform.
/// Creates a transform.
/// </para>
/// <para>
/// A transform copies data from source indices, transforms it, and persists it into an entity-centric destination index. You can also think of the destination index as a two-dimensional tabular data structure (known as
/// a data frame). The ID for each document in the data frame is generated from a hash of the entity, so there is a
/// unique row per entity.
/// </para>
/// <para>
/// You must choose either the latest or pivot method for your transform; you cannot use both in a single transform. If
/// you choose to use the pivot method for your transform, the entities are defined by the set of <c>group_by</c> fields in
/// the pivot object. If you choose to use the latest method, the entities are defined by the <c>unique_key</c> field values
/// in the latest object.
/// </para>
/// <para>
/// You must have <c>create_index</c>, <c>index</c>, and <c>read</c> privileges on the destination index and <c>read</c> and
/// <c>view_index_metadata</c> privileges on the source indices. When Elasticsearch security features are enabled, the
/// transform remembers which roles the user that created it had at the time of creation and uses those same roles. If
/// those roles do not have the required privileges on the source and destination indices, the transform fails when it
/// attempts unauthorized operations.
/// </para>
/// <para>
/// NOTE: You must use Kibana or this API to create a transform. Do not add a transform directly into any
/// <c>.transform-internal*</c> indices using the Elasticsearch index API. If Elasticsearch security features are enabled, do
/// not give users any privileges on <c>.transform-internal*</c> indices. If you used transforms prior to 7.5, also do not
/// give users any privileges on <c>.data-frame-internal*</c> indices.
/// </para>
/// </summary>
public sealed partial class PutTransformRequestDescriptor : RequestDescriptor<PutTransformRequestDescriptor, PutTransformRequestParameters>
{
	internal PutTransformRequestDescriptor(Action<PutTransformRequestDescriptor> configure) => configure.Invoke(this);

	public PutTransformRequestDescriptor(Elastic.Clients.Elasticsearch.Id transformId) : base(r => r.Required("transform_id", transformId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.TransformManagementPutTransform;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "transform.put_transform";

	public PutTransformRequestDescriptor DeferValidation(bool? deferValidation = true) => Qs("defer_validation", deferValidation);
	public PutTransformRequestDescriptor Timeout(Elastic.Clients.Elasticsearch.Duration? timeout) => Qs("timeout", timeout);

	public PutTransformRequestDescriptor TransformId(Elastic.Clients.Elasticsearch.Id transformId)
	{
		RouteValues.Required("transform_id", transformId);
		return Self;
	}

	private string? DescriptionValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Destination DestValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor DestDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor> DestDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Latest? LatestValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor LatestDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor> LatestDescriptorAction { get; set; }
	private IDictionary<string, object>? MetaValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Pivot? PivotValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor PivotDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor> PivotDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicy? RetentionPolicyValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor RetentionPolicyDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor> RetentionPolicyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Settings? SettingsValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor SettingsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor> SettingsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Source SourceValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor SourceDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor> SourceDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.Sync? SyncValue { get; set; }
	private Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor SyncDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor> SyncDescriptorAction { get; set; }

	/// <summary>
	/// <para>
	/// Free text description of the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Description(string? description)
	{
		DescriptionValue = description;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The destination for the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Dest(Elastic.Clients.Elasticsearch.TransformManagement.Destination dest)
	{
		DestDescriptor = null;
		DestDescriptorAction = null;
		DestValue = dest;
		return Self;
	}

	public PutTransformRequestDescriptor Dest(Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor descriptor)
	{
		DestValue = null;
		DestDescriptorAction = null;
		DestDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Dest(Action<Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor> configure)
	{
		DestValue = null;
		DestDescriptor = null;
		DestDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval between checks for changes in the source indices when the transform is running continuously. Also
	/// determines the retry interval in the event of transient failures while the transform is searching or indexing.
	/// The minimum value is <c>1s</c> and the maximum is <c>1h</c>.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The latest method transforms the data by finding the latest document for each unique key.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Latest(Elastic.Clients.Elasticsearch.TransformManagement.Latest? latest)
	{
		LatestDescriptor = null;
		LatestDescriptorAction = null;
		LatestValue = latest;
		return Self;
	}

	public PutTransformRequestDescriptor Latest(Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor descriptor)
	{
		LatestValue = null;
		LatestDescriptorAction = null;
		LatestDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Latest(Action<Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor> configure)
	{
		LatestValue = null;
		LatestDescriptor = null;
		LatestDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines optional transform metadata.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
	{
		MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The pivot method transforms the data by aggregating and grouping it. These objects define the group by fields
	/// and the aggregation to reduce the data.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Pivot(Elastic.Clients.Elasticsearch.TransformManagement.Pivot? pivot)
	{
		PivotDescriptor = null;
		PivotDescriptorAction = null;
		PivotValue = pivot;
		return Self;
	}

	public PutTransformRequestDescriptor Pivot(Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor descriptor)
	{
		PivotValue = null;
		PivotDescriptorAction = null;
		PivotDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Pivot(Action<Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor> configure)
	{
		PivotValue = null;
		PivotDescriptor = null;
		PivotDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines a retention policy for the transform. Data that meets the defined criteria is deleted from the
	/// destination index.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor RetentionPolicy(Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicy? retentionPolicy)
	{
		RetentionPolicyDescriptor = null;
		RetentionPolicyDescriptorAction = null;
		RetentionPolicyValue = retentionPolicy;
		return Self;
	}

	public PutTransformRequestDescriptor RetentionPolicy(Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor descriptor)
	{
		RetentionPolicyValue = null;
		RetentionPolicyDescriptorAction = null;
		RetentionPolicyDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor RetentionPolicy(Action<Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor> configure)
	{
		RetentionPolicyValue = null;
		RetentionPolicyDescriptor = null;
		RetentionPolicyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines optional transform settings.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Settings(Elastic.Clients.Elasticsearch.TransformManagement.Settings? settings)
	{
		SettingsDescriptor = null;
		SettingsDescriptorAction = null;
		SettingsValue = settings;
		return Self;
	}

	public PutTransformRequestDescriptor Settings(Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor descriptor)
	{
		SettingsValue = null;
		SettingsDescriptorAction = null;
		SettingsDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Settings(Action<Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor> configure)
	{
		SettingsValue = null;
		SettingsDescriptor = null;
		SettingsDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The source of the data for the transform.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Source(Elastic.Clients.Elasticsearch.TransformManagement.Source source)
	{
		SourceDescriptor = null;
		SourceDescriptorAction = null;
		SourceValue = source;
		return Self;
	}

	public PutTransformRequestDescriptor Source(Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor descriptor)
	{
		SourceValue = null;
		SourceDescriptorAction = null;
		SourceDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Source(Action<Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor> configure)
	{
		SourceValue = null;
		SourceDescriptor = null;
		SourceDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines the properties transforms require to run continuously.
	/// </para>
	/// </summary>
	public PutTransformRequestDescriptor Sync(Elastic.Clients.Elasticsearch.TransformManagement.Sync? sync)
	{
		SyncDescriptor = null;
		SyncDescriptorAction = null;
		SyncValue = sync;
		return Self;
	}

	public PutTransformRequestDescriptor Sync(Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor descriptor)
	{
		SyncValue = null;
		SyncDescriptorAction = null;
		SyncDescriptor = descriptor;
		return Self;
	}

	public PutTransformRequestDescriptor Sync(Action<Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor> configure)
	{
		SyncValue = null;
		SyncDescriptor = null;
		SyncDescriptorAction = configure;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(DescriptionValue))
		{
			writer.WritePropertyName("description");
			writer.WriteStringValue(DescriptionValue);
		}

		if (DestDescriptor is not null)
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, DestDescriptor, options);
		}
		else if (DestDescriptorAction is not null)
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.DestinationDescriptor(DestDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("dest");
			JsonSerializer.Serialize(writer, DestValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (LatestDescriptor is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, LatestDescriptor, options);
		}
		else if (LatestDescriptorAction is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.LatestDescriptor(LatestDescriptorAction), options);
		}
		else if (LatestValue is not null)
		{
			writer.WritePropertyName("latest");
			JsonSerializer.Serialize(writer, LatestValue, options);
		}

		if (MetaValue is not null)
		{
			writer.WritePropertyName("_meta");
			JsonSerializer.Serialize(writer, MetaValue, options);
		}

		if (PivotDescriptor is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, PivotDescriptor, options);
		}
		else if (PivotDescriptorAction is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.PivotDescriptor(PivotDescriptorAction), options);
		}
		else if (PivotValue is not null)
		{
			writer.WritePropertyName("pivot");
			JsonSerializer.Serialize(writer, PivotValue, options);
		}

		if (RetentionPolicyDescriptor is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, RetentionPolicyDescriptor, options);
		}
		else if (RetentionPolicyDescriptorAction is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.RetentionPolicyDescriptor(RetentionPolicyDescriptorAction), options);
		}
		else if (RetentionPolicyValue is not null)
		{
			writer.WritePropertyName("retention_policy");
			JsonSerializer.Serialize(writer, RetentionPolicyValue, options);
		}

		if (SettingsDescriptor is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, SettingsDescriptor, options);
		}
		else if (SettingsDescriptorAction is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SettingsDescriptor(SettingsDescriptorAction), options);
		}
		else if (SettingsValue is not null)
		{
			writer.WritePropertyName("settings");
			JsonSerializer.Serialize(writer, SettingsValue, options);
		}

		if (SourceDescriptor is not null)
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, SourceDescriptor, options);
		}
		else if (SourceDescriptorAction is not null)
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SourceDescriptor(SourceDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("source");
			JsonSerializer.Serialize(writer, SourceValue, options);
		}

		if (SyncDescriptor is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, SyncDescriptor, options);
		}
		else if (SyncDescriptorAction is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.TransformManagement.SyncDescriptor(SyncDescriptorAction), options);
		}
		else if (SyncValue is not null)
		{
			writer.WritePropertyName("sync");
			JsonSerializer.Serialize(writer, SyncValue, options);
		}

		writer.WriteEndObject();
	}
}